import React from 'react'
import './App.css';
/**
 * 
 * 官方定义高阶组件（HOC）是 React 中用于**复用组件逻辑**的一种高级技巧。HOC 自身不是 React API 的一部分，它是一种基于 React 的组合特性而形成的设计模式。
   HOC 是单词 Heigher Order Component 缩写
   具体而言，高阶组件是参数为组件，返回值为新组件的函数。
 * 
 * 
 */

class Foo extends React.PureComponent {
  // state = {
  //   sw: document.documentElement.clientWidth
  // }

  // componentDidMount () {
  //   window.addEventListener('resize', () => {
  //     this.setState(() => ({ sw: document.documentElement.clientWidth }))
  //   }, false)
  // }

  // componentWillUnmount () {
  //   window.removeEventListener('resize')
  // }

  render () {
    return (
      <p className='FooContent'>当前的屏幕宽度为:{this.props.sw}</p>
    )
  }
}

class Bar extends React.PureComponent {
  // state = {
  //   sw: document.documentElement.clientWidth
  // }

  // componentDidMount () {
  //   window.addEventListener('resize', () => {
  //     this.setState(() => ({ sw: document.documentElement.clientWidth }))
  //   }, false)
  // }

  // componentWillUnmount () {
  //   window.removeEventListener('resize')
  // }

  render () {
    return (
      <button className='btn-content'>当前屏幕宽度为:{this.props.sw}</button>
    )
  }
}

// 定义一个高阶组件函数,来抽取逻辑重复的位置,提高逻辑复用.
const withResize = (Component) => {
  return class WrappedComponent extends React.PureComponent {
    //#region 抽离组件通用的逻辑部分
    state = {
      sw: document.documentElement.clientWidth
    }

    componentDidMount () {
      window.addEventListener('resize', () => {
        this.setState(() => ({ sw: document.documentElement.clientWidth }))
      }, false)
    }

    componentWillUnmount () {
      window.removeEventListener('resize')
    }
    //#endregion

    render () {
      // 将需要的数据以 props 的方式传递给被包装的组件
      return <Component {...this.state} />
    }
  }
}

const FooWithResize = withResize(Foo)
const BarWithResize = withResize(Bar)

function App () {
  return (
    <div className="App">
      <h2>Hello HOC - Highter Order Component</h2>
      <h3>将通用逻辑抽离,以便复用!</h3>
      {/* <Foo />
      <Bar /> */}
      <FooWithResize />
      <BarWithResize />
    </div>
  );
}
export default App;
